cmake_minimum_required(VERSION 3.18)
project(MyAMG LANGUAGES CXX CUDA)

set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CUDA_STANDARD 17)
set(CMAKE_CUDA_STANDARD_REQUIRED ON)

# 禁用 IPO/LTO
set(CMAKE_INTERPROCEDURAL_OPTIMIZATION OFF)

find_package(MPI REQUIRED)
find_package(OpenMP REQUIRED)
find_package(CUDAToolkit REQUIRED)

# 分离编译标志
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O2 -fno-lto -pg")
set(CMAKE_CUDA_FLAGS "${CMAKE_CUDA_FLAGS} -O2 -Xcompiler=-fno-lto")
set(CMAKE_CUDA_NVCC_FLAGS "${CMAKE_CUDA_NVCC_FLAGS} -pg")

set(CMAKE_CUDA_ARCHITECTURES native)

include_directories(
        ${CMAKE_SOURCE_DIR}/include
        ${CMAKE_SOURCE_DIR}/include/Smoother
        ${CMAKE_SOURCE_DIR}/include/utils
        ${CMAKE_SOURCE_DIR}/include/test
        ${CMAKE_SOURCE_DIR}/include/Data
        ${CMAKE_SOURCE_DIR}/include/Blas
        ${CMAKE_SOURCE_DIR}/include/Precond
        ${MPI_CXX_INCLUDE_DIRS}
        ${CUDAToolkit_INCLUDE_DIRS}
)

link_directories(
        ${CMAKE_SOURCE_DIR}/lib
)

file(GLOB MY_SOURCE_CPP "${CMAKE_SOURCE_DIR}/src/*.cpp")
file(GLOB MY_SOURCE_CU "${CMAKE_SOURCE_DIR}/src/*.cu")

# 明确标记 CUDA 文件
set_source_files_properties(${MY_SOURCE_CU} PROPERTIES LANGUAGE CUDA)

add_executable(main ${MY_SOURCE_CPP} ${MY_SOURCE_CU})

set_target_properties(main PROPERTIES
        CUDA_SEPARABLE_COMPILATION ON
        CUDA_RESOLVE_DEVICE_SYMBOLS ON  # 添加这一行
        INTERPROCEDURAL_OPTIMIZATION OFF
)

target_link_libraries(main
        yhamg
        ${MPI_CXX_LIBRARIES}
        OpenMP::OpenMP_CXX
        CUDA::cudart
        CUDA::cublas
        CUDA::cusparse
)

if(MPI_CXX_COMPILE_FLAGS)
    set_target_properties(main PROPERTIES
            COMPILE_FLAGS "${MPI_CXX_COMPILE_FLAGS}")
endif()

if(MPI_CXX_LINK_FLAGS)
    set_target_properties(main PROPERTIES
            LINK_FLAGS "${MPI_CXX_LINK_FLAGS}")
endif()

option(ENABLE_NCU_PROFILE "Enable Nsight Compute profiling after build" OFF)

if(ENABLE_NCU_PROFILE)
    find_program(NCU_EXECUTABLE ncu)

    if(NCU_EXECUTABLE)
        message(STATUS "Found Nsight Compute: ${NCU_EXECUTABLE}")

        string(TIMESTAMP PROFILE_DATE "%Y%m%d_%H%M%S")
        set(PROFILE_OUTPUT "${CMAKE_BINARY_DIR}/profile_output_${PROFILE_DATE}.ncu-rep")

        add_custom_command(
                TARGET main POST_BUILD
                COMMAND ${CMAKE_COMMAND} -E echo "Running Nsight Compute profiling..."
                COMMAND ${NCU_EXECUTABLE}
                --set full
                --export ${PROFILE_OUTPUT}
                --force-overwrite
                $<TARGET_FILE:main>
                # 在这里添加你的程序参数
                COMMAND ${CMAKE_COMMAND} -E echo "Profile saved to: ${PROFILE_OUTPUT}"
                WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
                COMMENT "Profiling with Nsight Compute (full preset)"
        )

        message(STATUS "NCU profiling enabled - output will be: profile_output_${PROFILE_DATE}.ncu-rep")
    else()
        message(WARNING "NCU profiling enabled but ncu executable not found in PATH")
    endif()
endif()